package nl.utwente.ewi.hmi.multitouch.drivers.dtproxy;

import java.net.DatagramPacket;
import java.nio.ByteBuffer;
import java.util.LinkedList;
import java.util.List;

public class DiamondTouchPacket {

	public final long deviceId;
	public final List<DiamondTouchFrame> frames;

	public final int columns;
	public final int rows;
	
	private DiamondTouchPacket(long deviceId, int columns, int rows, List<DiamondTouchFrame> frames) {
		this.deviceId = deviceId;
		this.columns = columns;
		this.rows = rows;
		this.frames = frames;
	}

	public static DiamondTouchPacket fromDatagramPacket(DatagramPacket packet) {
		ByteBuffer buffer = ByteBuffer.wrap(packet.getData());

		return fromByteBuffer(buffer); 
	}

	public static void toByteBuffer(DiamondTouchPacket packet, ByteBuffer buffer) {
		buffer.putLong(packet.deviceId);
		buffer.putInt(packet.frames.size());

		for(DiamondTouchFrame frame : packet.frames) {
			buffer.putLong(frame.timeStamp);
			buffer.putInt(frame.columns);
			buffer.putInt(frame.rows);
			buffer.putInt(frame.xSegments.size());
			buffer.putInt(frame.ySegments.size());

			for(DiamondTouchSegment segment : frame.xSegments) {
				buffer.putInt(segment.startPos);
				buffer.putInt(segment.maxPos);
				buffer.putInt(segment.endPos);
			}

			for(DiamondTouchSegment segment : frame.ySegments) {
				buffer.putInt(segment.startPos);
				buffer.putInt(segment.maxPos);
				buffer.putInt(segment.endPos);
			}
		}
	}
	
	public static DiamondTouchPacket fromByteBuffer(ByteBuffer buffer) {
		long deviceId = buffer.getLong();
		int frameCount = buffer.getInt();
		List<DiamondTouchFrame> frames = new LinkedList<DiamondTouchFrame>();

		int columns = 0;
		int rows = 0;

		for(int i = 0; i < frameCount; i++) {
			long timeStamp = buffer.getLong();
			columns = buffer.getInt();
			rows = buffer.getInt();
			int xSegmentCount = buffer.getInt();
			int ySegmentCount = buffer.getInt();

			List<DiamondTouchSegment> xSegments = new LinkedList<DiamondTouchSegment>();
			List<DiamondTouchSegment> ySegments = new LinkedList<DiamondTouchSegment>();

			for(int x = 0; x < xSegmentCount; x++) {
				int startPos = buffer.getInt();
				int maxPos = buffer.getInt();
				int endPos = buffer.getInt();

				xSegments.add(new DiamondTouchSegment(startPos, maxPos, endPos));
			}

			for(int y = 0; y < ySegmentCount; y++) {
				int startPos = buffer.getInt();
				int maxPos = buffer.getInt();
				int endPos = buffer.getInt();

				ySegments.add(new DiamondTouchSegment(startPos, maxPos, endPos));
			}

			frames.add(new DiamondTouchFrame(timeStamp, columns, rows, xSegments, ySegments));
		}
		
		return new DiamondTouchPacket(deviceId, columns, rows, frames);
		
	}
	
	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("device : ");
		builder.append(deviceId);
		builder.append(" [");
		builder.append(columns);
		builder.append('x');
		builder.append(rows);
		builder.append("] ");
		builder.append(frames);

		return builder.toString();
	}
	
	public static void main(String[] args) {
		byte[] backingBuffer = new byte[65536];
		
		List<DiamondTouchFrame> frames = new LinkedList<DiamondTouchFrame>();

		List<DiamondTouchSegment> segments = new LinkedList<DiamondTouchSegment>();
		
		segments.add(new DiamondTouchSegment(0, 10, 100));
		segments.add(new DiamondTouchSegment(150, 155, 160));
		
		frames.add(new DiamondTouchFrame(2000l ,200, 200, segments, new LinkedList<DiamondTouchSegment>()));
		frames.add(new DiamondTouchFrame(2001l ,200, 200, new LinkedList<DiamondTouchSegment>(), segments));
		frames.add(new DiamondTouchFrame(2002l ,200, 200, new LinkedList<DiamondTouchSegment>(), new LinkedList<DiamondTouchSegment>()));
		frames.add(new DiamondTouchFrame(2003l ,200, 200, new LinkedList<DiamondTouchSegment>(), new LinkedList<DiamondTouchSegment>()));
		
		DiamondTouchPacket test = new DiamondTouchPacket(12, 200, 200, frames);
		
		System.out.println(test);
		
		ByteBuffer bb = ByteBuffer.wrap(backingBuffer);
		
		toByteBuffer(test, bb);
		
		bb.rewind();
		
		System.out.println(fromByteBuffer(bb));

		System.out.println(bb.toString());

	
	}
}
